package meminin.id3;

import java.sql.Connection;
import java.util.ArrayList;
import meminin.model.DataRecord;
import meminin.model.Label;
import meminin.model.TrainingData;

public class ID3ModelGenerator {

    Connection sqlConn;

    public ID3ModelGenerator() {
    }

    public ID3Node generateModel(TrainingData examples, DataRecord exampleFilter, Label targetLabel, ArrayList<Label> labels) {
        // create a root for the tree
        ID3Node node = new ID3Node();
        if (examples.isAllConform(exampleFilter, targetLabel)) {
            // if the target attribute is the only one left, give label to node according as the target attribute
            ArrayList<DataRecord> records = examples.getRecords(exampleFilter, new ID3DataRecord());
            node.setClassLabelValue(records.get(0).getAttributeValue(targetLabel.getDesc()));
            System.out.println("Add a leaf with value : "+node.getClassLabelValue());
        } else if (labels.isEmpty()) {
            // if the attributes is empty, return the node with label = most common target attribute in example
            node.setClassLabelValue(examples.getMostCommonValue(exampleFilter, targetLabel));
            System.out.println("Add a leaf with value : "+node.getClassLabelValue());
        } else {
            // get attribute that best classifies examples
            Label label = ((ID3TrainingData) examples).getMostDistinctiveLabel(exampleFilter, labels, targetLabel);
            node.setClassLabel(label);
            System.out.println("Add a node with label : "+label.getDesc());
            // for each value of label, vi
            ArrayList<String> values = label.getValues();
            for (String value : values) {
                // add a new tree branch below the root
                ID3Node child = new ID3Node();
                // add the new value to the filter for the lower node
                DataRecord newFilter = exampleFilter.getCopy();
                newFilter.setAttributeValue(label.getDesc(), value);
                // if the examples set is empty, add a new leaf node with label = most common value
                if (examples.getRecordsCount(newFilter) == 0) {
                    ArrayList<DataRecord> records = examples.getRecords(exampleFilter, new ID3DataRecord());
                    child.setClassLabelValue(examples.getMostCommonValue(exampleFilter, targetLabel));
                } else {
                    ArrayList<Label> newAttributes = (ArrayList<Label>) labels.clone();
                    newAttributes.remove(label);
                    child = generateModel(examples, newFilter, targetLabel, newAttributes);
                }
                node.addChild(value, child);
                if(child.isBranch()){
                    System.out.println("Add a new branch with label "+child.getClassLabel().getDesc()+" as a child of "+label.getDesc()+" transition value "+value);
                }else if(child.isLeaf()){
                    System.out.println("Add a new leaf with value "+child.getClassLabelValue()+" as a child of "+label.getDesc()+" transition value "+value);
                }
            }
        }
        return node;
    }
}
